function Mine(tr,td,mineNum){
  this.tr = tr;//行数
  this.td = td;//列数
  this.mineNum = mineNum;//雷数
  
  this.squares = [];//存储所有方块信息，二维数组，行列顺序排放
  this.tds = [];//存储所有单元格DOM，二维数组
  this.surplusMine = mineNum;//剩余雷数
  this.wrong = false;//判断红旗下是否有错
  this.num = true;//非雷方块全翻出
  this.open = false;//方块是否翻出

  this.parent = document.querySelector('.gameBox')
}

//生成n个不重复数字(返回雷)
Mine.prototype.randomNum = function(){
  var square = new Array(this.tr*this.td);//创建一个有长度的空数组
  for (var i = 0; i < square.length; i++) {
    square[i] = i;
  }
  square.sort(function()
    {
      return Math.random()-0.5
  });
  return square.splice(this.tr*this.td-this.mineNum);
  //return square.slice(0,this.mineNum);
  //使用slice有时会出现目标数-1
}
Mine.prototype.init = function(){
  this.surplusMine = this.mineNum
  var rn = this.randomNum();
  var n = 0;
  for (var i=0; i<this.tr; i++) {
    this.squares[i] = [];
    for (var j=0; j<this.td; j++) {
      n++;
      //格子信息设置为坐标(x,y)，行跟列与坐标数值刚好相反
      //存储用行列，坐标便于计算位置
      //雷
      if(rn.indexOf(n)!=-1){
        this.squares[i][j] = {type:'mine',x:j,y:i};
      }else{
        //数字
        this.squares[i][j] = {type:'number',x:j,y:i,value:0};
      } 
    }
  }
  //取消右键菜单
  this.parent.oncontextmenu = function(){
    return false;
  }
  this.updateNumber();
  this.createDom();
  this.mineNumDom = document.querySelector('.mineNum');
  this.mineNumDom.innerText = this.surplusMine;
  
}

//创建表格
Mine.prototype.createDom = function(){
  var This = this;
  var table = document.createElement('table');
  for(var i=0;i<this.tr;i++){
    var domTr = document.createElement('tr');
    this.tds[i] = [];
    for(var j=0;j<this.td;j++){
      var domTd = document.createElement('td');

      domTd.pos = [i,j];//把格子行列数据存到格子里
      domTd.onmousedown = function(){
        This.play(event,this);
      }
      this.tds[i][j] = domTd;
     /*  if(this.squares[i][j].type == 'mine'){
        domTd.className = 'mine'
      }
      if(this.squares[i][j].type == 'number'){
        domTd.innerText = this.squares[i][j].value;
      } */

      domTr.appendChild(domTd);
    }
    table.appendChild(domTr);
  }
  this.parent.innerHTML = ''
  this.parent.appendChild(table);
  
}
//找方格(中心)周围8个格子
Mine.prototype.find = function(squares){
  var x = squares.x;
  var y = squares.y;
  var result = [];//二维数组
  /*
    x-1,y-1  x,y-1  x+1,y-1
    x-1,y    x,y    x+1,y-1
    x-1,y+1  x,y+1  x+1,y+1
  */
  //通过坐标循环九宫格
  for(var i=x-1;i<=x+1;i++){
    for(var j=y-1;j<=y+1;j++){
      if(i<0||j<0||i>this.td-1||j>this.tr-1//左上右下
        ||(i==x && j==y)//循环到自己
        ||this.squares[j][i]=='mine')//雷
        {
          continue;
      }
      result.push([j,i]);//返回行列形式
    }
  }

  return result;
}
//更新雷周围数字
Mine.prototype.updateNumber = function(){
  for(var i=0;i<this.tr;i++){
    for(var j=0;j<this.td;j++){
      if(this.squares[i][j].type == 'number'){
        continue;
      }
      var num = this.find(this.squares[i][j]);
      for(var k=0;k<num.length;k++){
        this.squares[num[k][0]][num[k][1]].value+=1;
      }
    }
  }
}
//所有数字被翻出
Mine.prototype.number = function(){
  this.num = true
  for(var i=0;i<this.tr;i++){
    for(var j=0;j<this.td;j++){
      if(!this.squares[i][j].open && this.squares[i][j].type=='number'){
        this.num = false
        return;
      }else if(this.squares[i][j].open && this.squares[i][j].type=='number'){
        this.num = true
        continue;
      }
    }
  }
}

Mine.prototype.play = function(ev,obj){
  var This = this;
  //点击的是左键
  if(ev.which==1&&obj.className!='flag'){
    var curSquare = this.squares[obj.pos[0]][obj.pos[1]]
    curSquare.open = true
    if(curSquare.type == 'number'){
      obj.innerText = curSquare.value
      if(curSquare.value == 0){
        obj.innerText = '';
        obj.className = 'zero'
        findZero(curSquare);
        function findZero(curSquare){
          var around = This.find(curSquare);
          for(var i=0;i<around.length;i++){
            var x = around[i][0];//行
            var y = around[i][1];//列
            if(This.squares[x][y].value == 0){
              This.squares[x][y].open = true
              This.tds[x][y].className = 'zero'
              if(!This.tds[x][y].check){
                This.tds[x][y].check = true;
                findZero(This.squares[x][y]);
              }
            }else{
              This.tds[x][y].innerText = This.squares[x][y].value;
              This.squares[x][y].open = true;
            }
          }
        }

      }
    }else{
      this.gameOver(obj);
    }
  }
  //埋旗
  if(ev.which==3){
    //数字不能埋旗
    if(this.tds[obj.pos[0]][obj.pos[1]].innerText){
      return;
    }
    //切换className
    obj.className = obj.className=='flag'?'':'flag';
    if(!this.wrong && this.squares[obj.pos[0]][obj.pos[1]].type != 'mine'){
      this.wrong = true;
    }
    if(obj.className == 'flag'){
      this.mineNumDom.innerText = --this.surplusMine;
    }else{
      this.mineNumDom.innerText = ++this.surplusMine;
    }
    if(this.surplusMine==0){
      if(this.wrong==false){
        alert("你好棒啊！游戏成功！")
      }else{
        alert("失败咯。")
      }
      for(var i=0;i<this.tr;i++){
        for(var j=0;j<this.td;j++){
          if(this.squares[i][j].type == 'mine'){
            this.tds[i][j].className = 'mine'
          }
          /* 取消所有格子的点击事件 */
          this.tds[i][j].onmousedown = null;
        }
      }
    }
  }
  this.number();
  if(this.num){
    alert("你好棒啊！游戏成功！")
  }
}
//游戏失败
Mine.prototype.gameOver = function(obj){
  for(var i=0;i<this.tr;i++){
    for(var j=0;j<this.td;j++){
      if(this.squares[i][j].type == 'mine'){
        this.tds[i][j].className = 'mine'
        obj.style.background = '#f00'
      }
      /* 取消所有格子的点击事件 */
      this.tds[i][j].onmousedown = null;
    }
  }
  alert("失败咯。")
}

var btns = document.querySelectorAll('button');
var mine = null;//实例
var ln = 0;//处理选中按钮颜色
var arr = [[10,10,10],[20,20,40],[30,30,90]]
for(let i=0;i<btns.length-1;i++){
  btns[i].onclick = function(){
    btns[ln].className = '';
    this.className = 'active';
    ln = i;

    mine = new Mine(...arr[i]);
    mine.init();
  }
}
btns[ln].onclick()
btns[3].onclick = function(){
  mine.init()
  mine.mineNumDom = document.querySelector('.mineNum');
  mine.mineNumDom.innerText = mine.mineNum;
}
/* var mine = new Mine(10,10,10);
mine.init(); */